﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Chisel.Core
{
	/// <summary>
	/// A background grid for a diagram.
	/// </summary>
	public class DiagramGrid : UserControl
	{

		public DiagramGrid()
			: base()
		{

			Spacing = 16;
			Thickness = 1;

			_path = new Path();
			Content = _path;

			Brush = new SolidColorBrush(Colors.LightGray) {
				Opacity = 0.75
			};

			Loaded += new RoutedEventHandler(OnLoaded);
		}


		private void OnLoaded(object sender, RoutedEventArgs e)
		{
			UpdateGrid();
		}

		/// <summary>
		/// The distance between the grid lines.
		/// </summary>
		public double Spacing { get; set; }

		/// <summary>
		/// The thickness of the grid lines.
		/// </summary>
		public double Thickness { get; set; }

		/// <summary>
		/// The brush used to draw the grid lines.
		/// </summary>
		public Brush Brush { get; set; }

		private Path _path;


		/// <summary>
		/// Updates the grid geometry.
		/// </summary>
		public void UpdateGrid()
		{
			var geometry = new GeometryGroup();
			_path.Data = geometry;
			_path.Stroke = Brush;
			_path.StrokeThickness = Thickness;

			for (double y = 0; y < (Parent as Canvas).ActualHeight; y += Spacing)
			{
				var line = new LineGeometry() {
					StartPoint = new Point(0, y),
					EndPoint = new Point((Parent as Canvas).ActualWidth, y)
				};
				geometry.Children.Add(line);
			}

			for (double x = 0; x < (Parent as Canvas).ActualWidth; x += Spacing)
			{
				var line = new LineGeometry() {
					StartPoint = new Point(x, 0),
					EndPoint = new Point(x, (Parent as Canvas).ActualHeight)
				};
				geometry.Children.Add(line);
			}
		}


		/// <summary>
		/// Snaps the point to the grid lines.
		/// </summary>
		public Point SnapPoint(Point point)
		{
			var newPoint = point;
			newPoint.X = Math.Round(newPoint.X / Spacing) * Spacing;
			newPoint.Y = Math.Round(newPoint.Y / Spacing) * Spacing;
			return newPoint;
		}

	}
}
